
package com.tansun.easycare.rule.ruleproj.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import com.jeedev.msdp.base.entity.SysUser;
import com.jeedev.msdp.sys.entity.SysRole;
import com.tansun.easycare.core.utils.ResponseTable;
import com.tansun.easycare.modules.sys.service.RoleService;
import com.tansun.easycare.modules.sys.utils.UserUtils;
import com.tansun.easycare.rule.bakproject.service.IRuleProjectZipService;
import com.tansun.easycare.rule.bakproject.service.RuleProjectCopyService;
import com.tansun.easycare.rule.common.ResMessage;
import com.tansun.easycare.rule.common.RuleBaseController;
import com.tansun.easycare.rule.common.model.ResponseVO;
import com.tansun.easycare.rule.exception.DataEmptyException;
import com.tansun.easycare.rule.monitor.service.RuleMonitorInfoService;
import com.tansun.easycare.rule.ruleproj.entity.RuleAuthority;
import com.tansun.easycare.rule.ruleproj.entity.RuleProjEntity;
import com.tansun.easycare.rule.ruleproj.entity.RuleProject;
import com.tansun.easycare.rule.ruleproj.entity.RuleProjectRank;
import com.tansun.easycare.rule.ruleproj.model.ProjectModelInfo;
import com.tansun.easycare.rule.ruleproj.model.RuleConsoleModel;
import com.tansun.easycare.rule.ruleproj.model.RuleprojectVO;
import com.tansun.easycare.rule.ruleproj.service.RuleProjectRankService;
import com.tansun.easycare.rule.ruleproj.service.RuleProjectService;

import net.sf.json.JSONObject;
import static java.util.stream.Collectors.toList;

/**
 * 规则项目管理Controller
 *
 * @author lph
 * @version 2017-02-06
 */
@RestController
@RequestMapping(value = "/ruleProj/ruleProject")
public class RuleProjectController extends RuleBaseController {

    @Autowired
    private RuleProjectService ruleProjectService;
    
//    @Autowired
//    private UserDao userDao;
	@Autowired
	private RuleProjectRankService ruleProjectRankService;

    
    @Autowired
    private  IRuleProjectZipService  ruleProjectZipService;
    
    @Autowired 
    private RoleService roleService;
    @Autowired
    private RuleMonitorInfoService ruleMonitorInfoService;
    
    @Autowired
    private   RuleProjectCopyService    ruleProjectCopyService;
    
    /**
     * 规则项目列表
     *
     * @param entity      规则项目管理Entity
     * @return 项目列表
     */
    @RequestMapping("index")
    public ResponseTable<RuleprojectVO> index(@RequestBody RuleprojectVO entity) throws Exception {
//    	ResponseTable<RuleprojectVO>  resVo  = new  ResponseTable<>();
//        try {
        	PageInfo<RuleprojectVO> pageInfo = this.ruleProjectService.findPageRef(entity.getPage(), entity);
            return new  ResponseTable<RuleprojectVO>(pageInfo);
//        }catch(Exception e) {
//        	e.printStackTrace();
//        	resVo.setStatus(ResponseVO.ERROR);
//        	resVo.setDescription(e.getMessage());
//        }
//    	
//        return resVo;
    }
    
    /**
     * 规则控制台
     * @param projectCode
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("queryMyProject")
    public ResponseVO queryMyProject(String projectCode, Model model) throws Exception {
    	ResponseVO  res  = new ResponseVO();
    	RuleConsoleModel respModel = new RuleConsoleModel();
    	try {
    		List<RuleProject> ruleList = ruleProjectService.getRoleRuleAuthProj(projectCode,null);//获取当前用户具有权限的项目
            if (ruleList.size() >= 1) {
            	boolean isAuth = false;//检查当前传入的项目是否被授权
                for (RuleProject ruleProject : ruleList) {
					if(ruleProject.getProjectcode().equals(projectCode)) {	
						isAuth = true;
						break;
					}
				}
                //直接进入规则项目页面 呈现所有的第一个规则项目的内容
                if (projectCode == null || isAuth==false) {
                    projectCode = ruleList.get(0).getProjectcode();
                }

            	SysUser  currUser = UserUtils.getSysService().getCurrUser();
            	if (currUser == null || currUser.getUserNum() ==null) {
            		res.setStatus(1000);
            		res.setDescription("当前用户失效!");
            		return  res;
            	}  
                respModel.setProjectCode(projectCode);
                respModel.setRuleList(ruleList);
                List<RuleAuthority> list = ruleProjectService.getProjAuthInfoByRoleCode(projectCode, roleService.findRolesByUserNum(currUser.getUserNum()));
                String queryStr = mergerAuthority(list,1);
                String modifyStr =  mergerAuthority(list,2);
                respModel.setCurrAuth(queryStr);
                RuleProjectRank rankCondition = new RuleProjectRank();
                String mergerCode = mergerQueryAndModifyCode(queryStr,modifyStr);
                //根据mergerCode过滤rankList
                rankCondition.setProjectCode(projectCode);
                List<RuleProjectRank> ranklist = ruleProjectRankService.findList(rankCondition);
                ruleProjectRankService.initBaseModule(projectCode, projectCode,true,ranklist);
                if(ranklist.size()==0) {
                	ranklist = ruleProjectRankService.findList(rankCondition);
                }
                ruleProjectRankService.closeTree(ranklist);
                filterRankListByMergerCode(ranklist,mergerCode);
                respModel.setRanklist(ranklist);
            }else {
            	throw new DataEmptyException("该用户未分配项目权限,请切换账户或为该用户分配权限！");
            }
            res.setData(respModel);
    	}catch (Exception e) {
			// TODO: handle exception
    		e.printStackTrace();
    		res.setStatus(ResponseVO.ERROR);
    		res.setDescription(e.getMessage());
		}
        return res;
    }
    /**
     * 校验权限
     * @param projectCode
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("checkRuleProjectAuth")
    public ResponseVO checkRuleProjectAuth(String projectCode) throws Exception {
    	ResponseVO  res  = new ResponseVO();
    	RuleConsoleModel respModel = new RuleConsoleModel();
    	try {
    		List<RuleProject> ruleList = ruleProjectService.getRoleRuleAuthProj(projectCode,null);//获取当前用户具有权限的项目
            if (ruleList.size() >= 1) {
            	SysUser  currUser = UserUtils.getSysService().getCurrUser();
            	if (currUser == null || currUser.getUserNum() ==null) {
            		res.setStatus(1000);
            		res.setDescription("当前用户失效!");
            		return  res;
            	}  
                respModel.setProjectCode(projectCode);
                respModel.setRuleList(ruleList);
                List<RuleAuthority> list = ruleProjectService.getProjAuthInfoByRoleCode(projectCode, roleService.findRolesByUserNum(currUser.getUserNum()));
                String queryStr = mergerAuthority(list,1);
                String modifyStr =  mergerAuthority(list,2);
                respModel.setCurrAuth(queryStr);
                RuleProjectRank rankCondition = new RuleProjectRank();
                String mergerCode = mergerQueryAndModifyCode(queryStr,modifyStr);
                //根据mergerCode过滤rankList
                rankCondition.setProjectCode(projectCode);
                List<RuleProjectRank> ranklist = ruleProjectRankService.findList(rankCondition);
                ruleProjectRankService.initBaseModule(projectCode, projectCode,true,ranklist);
                if(ranklist.size()==0) {
                	ranklist = ruleProjectRankService.findList(rankCondition);
                }
                ruleProjectRankService.closeTree(ranklist);
                filterRankListByMergerCode(ranklist,mergerCode);
                respModel.setRanklist(ranklist);
            }else {
            	throw new DataEmptyException("该用户未分配项目权限,请切换账户或为该用户分配权限！");
            }
            res.setData(respModel);
    	}catch (Exception e) {
			// TODO: handle exception
    		e.printStackTrace();
    		res.setStatus(ResponseVO.ERROR);
    		res.setDescription(e.getMessage());
		}
        return res;
    }
    
    /**
     * 获取角色组
     * 
     */
    @RequestMapping("roleList")
    public ResponseVO roleList(@RequestBody SysRole role) throws Exception {
    	ResponseVO ret = new ResponseVO();
    	List<SysRole> roles = UserUtils.getSysService().getRoleList();
        ret.setData(roles);
        return ret;
    }
    

    /**
     * 获取角色修改权限 HX
     */
    @RequestMapping("getIsModify")
    public   ResponseVO getIsModify(@RequestBody ProjectModelInfo proModelInfo) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
        	SysUser  currUser = UserUtils.getSysService().getCurrUser();
        	if (currUser == null || currUser.getUserNum() ==null) {
        		ret.setStatus(1000);
        		ret.setDescription("当前用户失效!");
        		return  ret;
        	}        	
            List<RuleAuthority> list = ruleProjectService.getProjAuthInfoByRoleCode(proModelInfo.getProjectCode(), roleService.findRolesByUserNum(currUser.getUserNum()));
            for(RuleAuthority ruleAuthority: list){
                JSONObject  jasonObject = JSONObject.fromObject(ruleAuthority.getModifycode());
                Map<String,Object> map = (Map<String,Object>)jasonObject;
                if(map.containsKey(proModelInfo.getTreeId()) && map.get(proModelInfo.getTreeId()).equals("1")){
                	ret.setData((Serializable) true);
                	return ret;
                }

            }
        } catch (Exception e) {
            logger.debug(ExceptionUtils.getStackTrace(e));
            ret.setDescription("角色修改权限信息获取失败，请查看日志");
            ret.setStatus(ResponseVO.ERROR);
        }
        ret.setStatus(ResponseVO.ERROR); 
        ret.setData((Serializable) false);
        ret.setDescription("角色没有修改权限！");
        return ret;
    }
   
    /**
     * 规则项目管理详情
     *
     * @param projectCode 规则项目编码
     * @return 规则项目信息
     */
    @RequestMapping("ruleDetail")
    public  ResponseVO ruleDetail(@RequestBody RuleProject ruleProject) throws Exception {
    	ResponseVO  res  = new ResponseVO();
    	//获取当前用户的所有角色
    	SysUser  currUser = UserUtils.getSysService().getCurrUser();
    	if (currUser == null || currUser.getUserNum() ==null) {
    		res.setStatus(1000);
    		res.setDescription("当前用户失效!");
    		return  res;
    	} 
    	List<SysRole> userRoles = roleService.findRolesByUserNum(currUser.getUserNum());
		String rolesString = "";
		for(SysRole userRole : userRoles){
			rolesString = rolesString + userRole.getRemark();
		}
    	List<SysRole> roles = new ArrayList<SysRole>();
    	//获取创建项目的用户对应的所有角色
    	SysUser user =UserUtils.getSysService().get(ruleProject.getCreateBy());//获取该项目的创建用户
    	roles = roleService.findRolesByUserNum(user.getUserNum());
		if(rolesString.indexOf("sys_admin")>-1 ||rolesString.indexOf("superadmin")>-1|| ruleProject.getCreateBy()==null){
	        try {
	            List<RuleAuthority> authList = ruleProjectService.getProjAuthInfo(ruleProject.getProjectcode(), null);
	            res.setData((Serializable) authList);
	            return res;
	        } catch (Exception e) {
	        	 logger.debug(ExceptionUtils.getStackTrace(e));
	        	 res.setStatus(ResponseVO.ERROR);
	             res.setDescription("规则信息获取失败，请查看日志！");
	        }
		}else{
        	for(SysRole role : roles){
        		if(rolesString.indexOf(role.getRemark())>-1){
        	        try {
        	            List<RuleAuthority> authList = ruleProjectService.getProjAuthInfo(ruleProject.getProjectcode(), null);
        	            res.setData((Serializable) authList);
        	            return res;
        	        } catch (Exception e) {
        	        	logger.debug(ExceptionUtils.getStackTrace(e));
        	        	res.setStatus(ResponseVO.ERROR);
       	             	res.setDescription("规则信息获取失败，请查看日志！");
        	        }
        		}
        	}
		}
		res.setDescription("与创建人角色不同，无法操作！");
		res.setStatus(ResponseVO.ERROR);
        return res;
    }
   
   
    /**
     * 保存规则项目信息
     */
    @RequestMapping(value = "save")
    public @ResponseBody
    ResponseVO save(@RequestBody RuleProjEntity ruleProjEntity) {
    	ResponseVO ret = new ResponseVO();
        try {
            ruleProjectService.saveOrUpdate(ruleProjEntity);
            ret.setDescription("保存规则项目成功!");
        } catch (Exception e) {
        	e.printStackTrace();
        	ret.setDescription(e.getMessage());
            ret.setStatus(ResponseVO.ERROR);
        } 
        return ret;
    }
    
    /**
     * 修改 项目状态(假删除)
     *
     * @param projectId 规则项目ID
     * @param status    修改的状态
     */
    @RequestMapping("ruleStatusChange")
    public 
    ResponseVO ruleStatusChange(@RequestBody RuleProject ruleProject) throws Exception {
    	ResponseVO ret = new ResponseVO();
        try {
            RuleProject rule = ruleProjectService.get(ruleProject.getId());            
            rule.setStatus("0");
            ruleProjectService.save(rule);
            ret.setDescription("删除规则项目成功");
        } catch (Exception e) {
            logger.debug(ExceptionUtils.getStackTrace(e));
            ret.setDescription(e.getMessage());;
            ret.setStatus(ResponseVO.ERROR);
        }
        return ret;
    }
    
    @RequestMapping("copyProject")
    public  ResponseVO   copyProject(@RequestBody RuleProject ruleProject) {
    	   ResponseVO   res  = new  ResponseVO();  
		   RuleProject  tmpProject  = new  RuleProject();
		   tmpProject.setProjectcode(ruleProject.getTargetProjectCode());
		   tmpProject.setProjectname(ruleProject.getProjectname());
		   String  msg =this.ruleProjectService.isExist(tmpProject);
		   if (msg.length() >0) {
			   res.setStatus(ResponseVO.ERROR);
			   res.setDescription(msg);
			   return res;
		   }
    	   try {
    		   this.ruleProjectCopyService.createProjectInfo(ruleProject.getProjectcode(), ruleProject.getTargetProjectCode());
    	      this.ruleProjectCopyService.copyProject(ruleProject.getProjectcode(), ruleProject.getTargetProjectCode(), ruleProject.getProjectname());
    	   }catch (Exception e) {
			  res.setDescription(e.getMessage());
			  res.setStatus(ResponseVO.ERROR);
			  this.ruleProjectCopyService.upateProjectRes(ruleProject.getProjectcode(), ruleProject.getTargetProjectCode(), "-1");
		   }finally {
			   this.ruleProjectCopyService.deleteProjectCopy(ruleProject.getProjectcode());
		   }
    	   this.ruleProjectCopyService.upateProjectRes(ruleProject.getProjectcode(), ruleProject.getTargetProjectCode(), "2");
    	   return  res;    	
    }
    
    /**
     * 删除规则项目信息(真删除)
     */
    @RequestMapping(value = "delete")
    public ResponseVO delete(@RequestBody RuleProject ruleProject) {
    	ResponseVO ret = new ResponseVO();
    	try {
    		ruleProjectService.delete(ruleProject);
    		ret.setDescription("删除规则项目成功");
        } catch (Exception e) {
            logger.debug(ExceptionUtils.getStackTrace(e));
            ret.setDescription(e.getMessage());;
            ret.setStatus(ResponseVO.ERROR);
        }
        return ret;
        		   
        
    }
    
    
//    /**
//     * 获取所有用户 author WY
//     */
//    @RequestMapping("zuserData")
//    public void ruleSetEditJsonData(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        List<SysUser> users = UserUtils.getUserListByRole("");
//        List<Map<String, Object>> listZuser = new ArrayList<Map<String, Object>>();
//        for (SysUser sysUser : users) {
//            Map<String, Object> map = new HashMap<String, Object>();
//            map.put("id", sysUser.getLoginName());
//            map.put("name", sysUser.getName());
//            listZuser.add(map);
//
//        }
//        String jsondata = JSON.toJSONString(listZuser);
//
//        response.setContentType("application/json;charset=UTF-8");
//        PrintWriter writer = response.getWriter();
//        writer.print(jsondata);
//        writer.flush();
//    }
    
    
    @RequestMapping("bakRuleProject")
    public    void    bakRuleProject(HttpServletRequest req, HttpServletResponse res,@RequestBody RuleProject ruleProject) {

    	OutputStream os =null;
        //res.reset();
        res.setContentType("application/octet-stream; charset=utf-8");
        res.setHeader("Content-Disposition", "attachment; filename=" + ruleProject.getProjectcode()+".zip");
        String userAgent = req.getHeader("User-Agent");
        if (userAgent == null)
            userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
    	try {
    		os = res.getOutputStream();
    		InputStream  is =ruleProjectZipService.bakRuleProject(ruleProject.getProjectcode());
    		byte[] b  = new  byte[1024];
    		while ((is.read(b) !=-1)) {
    			os.write(b);
    		}
    		os.flush();
    		is.close();
    	}catch(Exception e) {
             e.printStackTrace();
    	}finally {
    		if (os != null) {
    			try {
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    		} 
    	}
    	
    }
    
    @RequestMapping("resRuleProject")
    public   void    resRuleProject(@RequestParam("file") MultipartFile file,HttpServletRequest request, HttpServletResponse res,String dataOprType) {
        PrintWriter pw= null;
        String  projectCode= null;
        ResMessage msg = new ResMessage("success", "上传成功");
        try {
        	pw = res.getWriter();
        	if (dataOprType.toUpperCase().equals("INSERT")) {
        		RuleProject  ruleProject  = new  RuleProject();
        		projectCode=ruleProjectZipService.parseProjectCode(file.getInputStream()).split("/")[0]; //以流的方式获取projectCode
        		ruleProject.setProjectcode(projectCode);
        	    List<RuleProject>  list =	this.ruleProjectService.findList(ruleProject);
        	    if (list != null && list.size() >0) {
        	    	msg = new ResMessage("failure", "项目已经存在");
        	    	pw.write(JSONArray.toJSONString(msg));
        	        pw.flush();
        	        pw.close();
        	        return ;
        	    }
        	}else {
        		projectCode=ruleProjectZipService.parseProjectCode(file.getInputStream()).split("/")[0]; //以流的方式获取projectCode
        	}
			ruleProjectZipService.restoreRuleProject(file.getInputStream(),projectCode,dataOprType);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			msg = new ResMessage("failure", e.getMessage());
		} 
        pw.write(JSONArray.toJSONString(msg));
        pw.flush();
        pw.close();
    }


    @RequestMapping("ruleHelper")
    public String ruleHelper(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return "rule/ruleproj/operationManual";
    }

    private String mergerAuthority(List<RuleAuthority> list,int type){
        if(list.size()==1){
            if(type==1){
                return list.get(0).getQuerycode();
            }else {
                return list.get(0).getModifycode();
            }

        }else{
            Map<String,Object> mergerMap = new HashMap<>();
            if(type == 1){
                mergerMap = (Map<String,Object>)JSON.parse(list.get(0).getQuerycode());
            }else{
                mergerMap = (Map<String,Object>)JSON.parse(list.get(0).getModifycode());
            }
            for(int i=0;i<list.size();i++){
                if(i==0){
                    continue;
                }
                String querycode = "";
                if(type==1){
                    querycode = list.get(i).getQuerycode();
                }else {
                    querycode = list.get(i).getModifycode();
                }
                Map<String,Object> map = (Map<String,Object>)JSON.parse(querycode);
                Set<Map.Entry<String, Object>> entries = map.entrySet();
                for(Map.Entry<String, Object> entry :entries){
                    if("1".equals(entry.getValue())){
                        mergerMap.put(entry.getKey(),"1");
                    }
                }
            }
            return JSON.toJSONString(mergerMap);
        }
    }

    //合并查询和修改功能
   private String mergerQueryAndModifyCode(String querycode,String modifycode){
       Map<String,Object> queryMap = (Map<String,Object>)JSON.parse(querycode);
       Map<String,Object> modifyMap = (Map<String,Object>)JSON.parse(modifycode);
       Set<Map.Entry<String, Object>> entries = modifyMap.entrySet();
       for(Map.Entry<String, Object> entry :entries){
           if("1".equals(entry.getValue())){
               queryMap.put(entry.getKey(),"1");
           }
       }
        return JSON.toJSONString(queryMap);
   }

   private  void filterRankListByMergerCode(List<RuleProjectRank> list,String mergerStr){
       Map<String,Object> modifyMap = (Map<String,Object>)JSON.parse(mergerStr);
       Set<Map.Entry<String, Object>> entries = modifyMap.entrySet();
       Iterator<RuleProjectRank> iterator = list.iterator();
       while(iterator.hasNext()){
           RuleProjectRank ruleProjectRank = iterator.next();
           if((!modifyMap.containsKey(ruleProjectRank.getModuleType()) 
        		   && !"file".equals(ruleProjectRank.getModuleType()))
        		   || (modifyMap.containsKey(ruleProjectRank.getModuleType())
        				   && !"1".equals(modifyMap.get(ruleProjectRank.getModuleType())))){
        	   
               iterator.remove();
           }
       }
   }


    /**
     * 获取项目  监控图标用
     * @param projectCode
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("queryMyProjectForMonitor")
    public ResponseVO queryMyProjectForMonitor(String projectCode, Model model) throws Exception {
        ResponseVO  res  = new ResponseVO();
        RuleConsoleModel respModel = new RuleConsoleModel();
        try {
            List<RuleProject> ruleList = ruleProjectService.getRoleRuleAuthProj(projectCode,null);//获取当前用户具有权限的项目
            if (ruleList.size() >= 1) {
                List<String> monitorList = ruleMonitorInfoService.getProjectCodeList();
                if(monitorList==null || monitorList.size()==0){
                    respModel.setRuleList(new ArrayList<>());
                    res.setData(respModel);
                    return res;
                }
                List<RuleProject> intersection = ruleList.stream().filter(item -> monitorList.contains(item.getProjectcode())).collect(toList());
                intersection.parallelStream().forEach(System.out :: println);
                respModel.setRuleList(intersection);
            }else {
                respModel.setRuleList(new ArrayList<>());
            }
            res.setData(respModel);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            res.setStatus(ResponseVO.ERROR);
            res.setDescription(e.getMessage());
        }
        return res;
    }

}